<template>
	<view :style="'color:'+shallowColor" class="waterfall-index">
		<view class="waterfall_flow" :style="`margin:0px ${flowData.px}px;`" :key="'wf_'+flowData.column">
			<view :id="`cont_${index + 1}`" class="cont-box " :style="columnStyle(index)"
				v-for="(numVal, index) in flowData.column" :key="numVal">
				<view class="list-box" v-for="(item, j) in flowData[`column_${index + 1}`]" :key="item._id + '_' + j">
					<waterfallItem :type="resType(item.type)" :index="index" :j="j" :flowData="flowData" :item="item"
						@load="imgLoad(item)" @error="imgError(item)">
					</waterfallItem>
				</view>
			</view>
		</view>
		<uv-text style="margin-bottom: 20px;" v-if="flowData.list[0]&&status=='nomore'" align="center" type="info"
			:text="nomoreText"></uv-text>
		<tabbars :prop-value="'mapping'"></tabbars>
		<uv-toast ref="toast"></uv-toast>
	</view>
</template>

<script>
	// 引入
	import waterfallItem from './waterfallItem.vue';
	import tabbars from '@/components/tabbar/tabbar.vue';
	import config from '@/common/config';
	import sharePoster from '@/components/sharePoster/sharePoster.vue';
	import {
		getName,
		like,
	} from '@/common/api.js';
	import {
		uv_image,
	} from '@/common/fun.js';
	export default {
		props: {
			type: {
				type: String,
				default: 'index'
			},
			tag: {
				type: String,
				default: ''
			},
			search: {
				type: String,
				default: ''
			},
			aside: {
				aside: Boolean,
				default: false
			},
			disabled: {
				aside: Boolean,
				default: false
			},
			size: {
				aside: [Number, String],
				default: 20
			},
			newColumnCount: {
				aside: [Number, String],
				default: 2
			},
			userId: {
				aside: String,
				default: ''
			},
		},
		components: {
			// 注册组件
			tabbars,
			sharePoster,
			waterfallItem,
		},
		data() {
			return {
				pageSize: Number(this.size),
				page: 1,
				total: 50, //总条数
				status: 'nomore',
				loading: true,
				// loadingText: '正在加载...',
				// loadmoreText: '加载更多',
				nomoreText: '没有更多了',

				tabbar: config.tabbar,
				deepColor: '#4D4D4D',
				shallowColor: '#808080',
				lightColor: '#ccc',
				dvcurrent: 0,
				adjustColumn: null,
				shareShow: false,
				shareIndex: null,
				flowData: {
					px: 5,
					list: [], // 数据值
					column: 1, // 瀑布列数
					clickIndex: [-1, -1], // 当前鼠标点击的项索引
					hoverIndex: [-1, -1], // 当前鼠标悬浮的项索引
				},

				heightCache: null, // 列高缓存
				getLoading: false,
				processedIndices: new Set(),
				preloadData: {},
			}
		},
		computed: {
			columnStyle() {
				return index => ({
					width: `calc(${100/this.flowData.column}% - ${this.flowData.px}px)`,
				});
			},
			CalcW() {
				return `${this.flowData.column}` > 3;
			},
		},
		watch: {
			shareIndex(newVal, oldVal) {
				this.shareShow = false;
			},
			'flowData.column'(newVal) {
				this.processedIndices = new Set();
			},
			tag(newVal, oldVal) {
				this.restq();
			},
			search(newVal, oldVal) {
				this.restq();
			},
			aside(newVal) {
				var that = this;
				setTimeout(function() {
					that.adjustColumnCount();
				}, 1000)
			}
		},
		mounted() {
			const _this = this;
			this.adjustColumnCount();
			uni.onWindowResize((res) => {
				const that = this; // 保存组件实例的引用
				if (_this.adjustColumnCount()) {
					uni.$uv.debounce(() => that.adjustColumnCount(), 300);
				}
			});
			this.getVuex();
		},
		beforeDestroy() {
			this.heightCache = null;
			this.processedIndices.clear();
			this.flowData.list = [];
		},
		methods: {
			resType(e) {
				return 'index';
				if (e == 'article') {
					return 'article'
				} else {
					return 'index'
				}
			},
			restq() {
				this.pageSize = Number(this.size);
				this.page = 1;
				this.total = 50; //总条数
				this.status = 'nomore';
				this.loading = true;
				this.flowData = {
					list: [], // 数据值
					column: this.flowData.column, // 瀑布列数
					clickIndex: [-1, -1], // 当前鼠标点击的项索引
					hoverIndex: [-1, -1], // 当前鼠标悬浮的项索引
				};
				this.heightCache = null;
				this.processedIndices.clear();
				this.getVuex();
			},
			async getVuex(ee = false) {
				var that = this;
				const currentPage = ee ? this.page : 0;
				if (!ee) {
					this.preloadData = {};
					// 初始化列数据
					for (let i = 1; i <= this.flowData.column; i++) {
						this.$set(this.flowData, `column_${i}`, []);
					}
				}
				const res = await this.preloadNextPage(currentPage);
				if (res && res.data) {
					// 处理数据渲染
					let len = this.flowData.list.length;;
					this.flowData.list = ee ? [...this.flowData.list, ...res.data] :
						res.data;
					// 在数据更新时使用$nextTick
					this.$nextTick(() => {
						this.initValue(ee ? len : 0);
						// this.$forceUpdate();
						// requestAnimationFrame(() => {
						// });
					});

					// 更新分页参数
					this.page = res.page + 1;
					this.total = res.total;
					this.status = res.page * res.pageSize < res.total ? 'loadmore' : 'nomore';
					// 预加载下一页资源
					if (this.status === 'loadmore') {
						this.$nextTick(() => this.preloadNextPage(this.page));
					}
				}
			},
			async preloadNextPage(currentPage) {
				if (this.disabled) {
					if (this.page > 1) {
						return this.preloadData[0];
					}
				}
				if (this.preloadData && this.preloadData[currentPage]) {
					return this.preloadData[currentPage]
				} else {
					this.loading = true;
					const res = await getName(this.type == 'index' ? 'flow' : 'article', {
						custom: {
							auth: true,
							toast: false,
						},
						params: {
							list: 'true',
							pageSize: this.pageSize,
							page: currentPage,
							tag: this.tag,
							userId: this.userId,
							search: this.search
						}
					});
					// 预加载图片资源
					if (res?.data && Array.isArray(res.data)) {
						res.data.forEach(item => {
							const img = new Image();
							img.src = uv_image(item);
							// 错误处理
							// img.onerror = () => console.error('图片预加载失败:', img.src);
						});
					}
					this.preloadData[currentPage] = res
					// 清理旧缓存（保留最近5页）
					const keys = Object.keys(this.preloadData);
					if (keys.length > 5) {
						// 删除最旧的缓存（页码最小的）
						const minKey = Math.min(...keys.map(Number));
						delete this.preloadData[minKey];
					}
					return res;
				}
			},
			loadMore() {
				const that = this; // 保存组件实例的引用
				uni.$uv.throttle(this.toNext, 600);
			},
			async toNext() {
				var that = this;
				if (this.loading || this.status !== 'loadmore') return;
				this.loading = true;
				try {
					console.log('加载中。。。');
					await this.getVuex(true);
				} finally {
					this.loading = false;
				}
			},
			titlePrompt(e) {
				if (e.content[0].userPrompt && e.content[0].videoUrl) {
					return e.content[0].userPrompt;
				}
				if (e.content[0].revised_prompt && e.content[0].url) {
					return e.content[0].revised_prompt;
				}
				if (e.content[0]?.data && e.content[0].data[0]) {
					return e.content[0].data[0].revised_prompt
				}
				if (e.content[0].prompt) {
					return e.content[0].prompt;
				}
				if (e.content[0]?.musics) {
					return e.content[0].musics[0].title;
				}
			},
			adjustColumnCount() {
				var that = this;
				const query = uni.createSelectorQuery().in(this);
				query.select('.waterfall-index').boundingClientRect(data => {
					if (data) {
						that.adjustColumn = data;
						that.refreshWaterfall(data);
					}
				}).exec();
			},
			refreshWaterfall(data) {
				if (!data || (data && !data.width)) return;
				let newColumnCount = Math.floor(data.width / 250);
				if (newColumnCount <= 1) {
					newColumnCount = Number(this.newColumnCount);
				}
				if (newColumnCount !== this.flowData.column) {
					this.flowData.column = newColumnCount;
					/* 瀑布流-初始化每一列的数据 */
					for (let i = 1; i <= this.flowData.column; i++) {
						this.$set(this.flowData, `column_${i}`, []);
					}
					this.$nextTick(() => {
						this.initValue(0); // 数据初始化
					});
				}
			},
			/* 获取最小值的对象 */
			getMinObj(a, s) {
				let m = a[0][s];
				let mo = a[0];
				for (let i = a.length - 1; i >= 0; i--) {
					if (a[i][s] < m) m = a[i][s];
				}
				mo = a.filter(i => i[s] === m);
				return mo[0];
			},
			/* 计算每列的高度 */
			getMinColumnHeight() {
				return new Promise(resolve => {
					const heightArr = [];
					// 确保在DOM更新后执行查询
					for (let i = 1; i <= this.flowData.column; i++) {
						uni.createSelectorQuery()
							.in(this)
							.select(`#cont_${i}`)
							.boundingClientRect(res => {
								heightArr.push({
									column: i,
									height: res.height
								});
							})
							.exec(() => {
								if (this.flowData.column <= heightArr.length) {
									this.heightCache = heightArr; // 缓存结果
									resolve(this.getMinObj(heightArr, "height"));
								}
							});
					}
				});
			},
			async throttledGetMinHeight(i) {
				if (this.heightCache) {
					return this.getMinObj(Object.values(this.heightCache), "height");
				}
				return await this.getMinColumnHeight();
			},
			/* 初始化瀑布流数据 */
			async initValue(i) {
				if (i >= this.flowData.list.length) {
					this.loading = false;
					return false;
				}

				const minHeightRes = await this.throttledGetMinHeight();
				if (this.flowData[`column_${minHeightRes.column}`]) {
					this.$set(
						this.flowData[`column_${minHeightRes.column}`],
						this.flowData[`column_${minHeightRes.column}`].length, {
							...this.flowData.list[i],
							index: i
						}
					);
				}

				this.$nextTick(() => {
					this.getMinColumnHeight();
				});
			},
			/* 图片加载完成 */
			imgLoad(e) {
				if (e._id !== undefined && !this.processedIndices.has(e._id)) {
					this.processedIndices.add(e._id);
					this.initValue(e.index + 1);
				}
			},
			/* 图片加载失败 */
			imgError(e) {
				if (e._id !== undefined && !this.processedIndices.has(e._id)) {
					this.processedIndices.add(e._id);
					e.__img__ = null; // 手动解除引用
					this.initValue(e.index + 1); // 加载下一条数据
				}
			},
			routed(url = '') {
				if (!url) {
					return;
				}
				uni.$uv.route({
					url: url
				})
			}
		}
	}
</script>
<style scoped lang="scss">
	@import 'element-ui/lib/theme-chalk/display.css';

	body {
		overflow: hidden;
		/* 允许垂直滚动 */
		-webkit-overflow-scrolling: touch;
		/* 使用原生滚动，提高性能 */
		position: fixed;
		/* 固定body位置，防止反弹效果 */
		width: 100%;

		/* 确保宽度覆盖全屏 */
		.waterfall-index {
			width: 100%;
			height: 100%;
			overflow-x: hidden;
		}

		// 瀑布
		.waterfall_flow {
			padding: 0px;
			display: flex;
			justify-content: space-between;
			align-items: self-start;
			flex-wrap: wrap;

			.cont-box {
				$borderRadius: 25rpx;
				float: left;
				width: 100%;

				.list-box {
					width: 100%;
					margin-bottom: 1vh;
					padding: 0px;
					border-radius: $borderRadius;
					overflow: hidden;
				}
			}
		}
	}
</style>